{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "7149c7fe-029b-4fa7-b1e2-953819330356",
   "metadata": {},
   "source": [
    "## 1. 环境安装、导入、获取PerfXCloud API KEY"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "1ad46d87",
   "metadata": {},
   "outputs": [],
   "source": [
    "!pip install openai\n",
    "#!pip install openai -i https://pypi.tuna.tsinghua.edu.cn/simple"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 363,
   "id": "initial_id",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-10-08T06:00:38.272831Z",
     "start_time": "2024-10-08T06:00:38.248204Z"
    }
   },
   "outputs": [],
   "source": [
    "from openai import OpenAI\n",
    "\n",
    "# PerfXCloud中创建的令牌\n",
    "perfx_api_key='sk-xnitUDyQf5z0AFaV518f5606966d49Fb8bA1E940B4FcA087'"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "edd1903c-109c-415f-80a8-4f9882cd3a49",
   "metadata": {},
   "source": [
    "## 2. 参考资源\n",
    "- openai官方文档：https://platform.openai.com/docs/api-reference/\n",
    "- PerfXCloud文档中心：https://docs.perfxlab.cn/docs/intro\n",
    "- 在代码中查看API文档"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 356,
   "id": "db442928-f513-4329-8652-566eb93afae5",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "\u001b[1;31mSignature:\u001b[0m\n",
       "\u001b[0mclient\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mchat\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mcompletions\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mcreate\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m\n",
       "\u001b[0m    \u001b[1;33m*\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;33m\n",
       "\u001b[0m    \u001b[0mmessages\u001b[0m\u001b[1;33m:\u001b[0m \u001b[1;34m'Iterable[ChatCompletionMessageParam]'\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;33m\n",
       "\u001b[0m    \u001b[0mmodel\u001b[0m\u001b[1;33m:\u001b[0m \u001b[1;34m'Union[str, ChatModel]'\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;33m\n",
       "\u001b[0m    \u001b[0mfrequency_penalty\u001b[0m\u001b[1;33m:\u001b[0m \u001b[1;34m'Optional[float] | NotGiven'\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mNOT_GIVEN\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;33m\n",
       "\u001b[0m    \u001b[0mfunction_call\u001b[0m\u001b[1;33m:\u001b[0m \u001b[1;34m'completion_create_params.FunctionCall | NotGiven'\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mNOT_GIVEN\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;33m\n",
       "\u001b[0m    \u001b[0mfunctions\u001b[0m\u001b[1;33m:\u001b[0m \u001b[1;34m'Iterable[completion_create_params.Function] | NotGiven'\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mNOT_GIVEN\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;33m\n",
       "\u001b[0m    \u001b[0mlogit_bias\u001b[0m\u001b[1;33m:\u001b[0m \u001b[1;34m'Optional[Dict[str, int]] | NotGiven'\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mNOT_GIVEN\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;33m\n",
       "\u001b[0m    \u001b[0mlogprobs\u001b[0m\u001b[1;33m:\u001b[0m \u001b[1;34m'Optional[bool] | NotGiven'\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mNOT_GIVEN\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;33m\n",
       "\u001b[0m    \u001b[0mmax_completion_tokens\u001b[0m\u001b[1;33m:\u001b[0m \u001b[1;34m'Optional[int] | NotGiven'\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mNOT_GIVEN\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;33m\n",
       "\u001b[0m    \u001b[0mmax_tokens\u001b[0m\u001b[1;33m:\u001b[0m \u001b[1;34m'Optional[int] | NotGiven'\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mNOT_GIVEN\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;33m\n",
       "\u001b[0m    \u001b[0mmetadata\u001b[0m\u001b[1;33m:\u001b[0m \u001b[1;34m'Optional[Dict[str, str]] | NotGiven'\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mNOT_GIVEN\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;33m\n",
       "\u001b[0m    \u001b[0mn\u001b[0m\u001b[1;33m:\u001b[0m \u001b[1;34m'Optional[int] | NotGiven'\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mNOT_GIVEN\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;33m\n",
       "\u001b[0m    \u001b[0mparallel_tool_calls\u001b[0m\u001b[1;33m:\u001b[0m \u001b[1;34m'bool | NotGiven'\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mNOT_GIVEN\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;33m\n",
       "\u001b[0m    \u001b[0mpresence_penalty\u001b[0m\u001b[1;33m:\u001b[0m \u001b[1;34m'Optional[float] | NotGiven'\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mNOT_GIVEN\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;33m\n",
       "\u001b[0m    \u001b[0mresponse_format\u001b[0m\u001b[1;33m:\u001b[0m \u001b[1;34m'completion_create_params.ResponseFormat | NotGiven'\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mNOT_GIVEN\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;33m\n",
       "\u001b[0m    \u001b[0mseed\u001b[0m\u001b[1;33m:\u001b[0m \u001b[1;34m'Optional[int] | NotGiven'\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mNOT_GIVEN\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;33m\n",
       "\u001b[0m    \u001b[0mservice_tier\u001b[0m\u001b[1;33m:\u001b[0m \u001b[1;34m\"Optional[Literal['auto', 'default']] | NotGiven\"\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mNOT_GIVEN\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;33m\n",
       "\u001b[0m    \u001b[0mstop\u001b[0m\u001b[1;33m:\u001b[0m \u001b[1;34m'Union[Optional[str], List[str]] | NotGiven'\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mNOT_GIVEN\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;33m\n",
       "\u001b[0m    \u001b[0mstore\u001b[0m\u001b[1;33m:\u001b[0m \u001b[1;34m'Optional[bool] | NotGiven'\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mNOT_GIVEN\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;33m\n",
       "\u001b[0m    \u001b[0mstream\u001b[0m\u001b[1;33m:\u001b[0m \u001b[1;34m'Optional[Literal[False]] | Literal[True] | NotGiven'\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mNOT_GIVEN\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;33m\n",
       "\u001b[0m    \u001b[0mstream_options\u001b[0m\u001b[1;33m:\u001b[0m \u001b[1;34m'Optional[ChatCompletionStreamOptionsParam] | NotGiven'\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mNOT_GIVEN\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;33m\n",
       "\u001b[0m    \u001b[0mtemperature\u001b[0m\u001b[1;33m:\u001b[0m \u001b[1;34m'Optional[float] | NotGiven'\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mNOT_GIVEN\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;33m\n",
       "\u001b[0m    \u001b[0mtool_choice\u001b[0m\u001b[1;33m:\u001b[0m \u001b[1;34m'ChatCompletionToolChoiceOptionParam | NotGiven'\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mNOT_GIVEN\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;33m\n",
       "\u001b[0m    \u001b[0mtools\u001b[0m\u001b[1;33m:\u001b[0m \u001b[1;34m'Iterable[ChatCompletionToolParam] | NotGiven'\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mNOT_GIVEN\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;33m\n",
       "\u001b[0m    \u001b[0mtop_logprobs\u001b[0m\u001b[1;33m:\u001b[0m \u001b[1;34m'Optional[int] | NotGiven'\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mNOT_GIVEN\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;33m\n",
       "\u001b[0m    \u001b[0mtop_p\u001b[0m\u001b[1;33m:\u001b[0m \u001b[1;34m'Optional[float] | NotGiven'\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mNOT_GIVEN\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;33m\n",
       "\u001b[0m    \u001b[0muser\u001b[0m\u001b[1;33m:\u001b[0m \u001b[1;34m'str | NotGiven'\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mNOT_GIVEN\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;33m\n",
       "\u001b[0m    \u001b[0mextra_headers\u001b[0m\u001b[1;33m:\u001b[0m \u001b[1;34m'Headers | None'\u001b[0m \u001b[1;33m=\u001b[0m \u001b[1;32mNone\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;33m\n",
       "\u001b[0m    \u001b[0mextra_query\u001b[0m\u001b[1;33m:\u001b[0m \u001b[1;34m'Query | None'\u001b[0m \u001b[1;33m=\u001b[0m \u001b[1;32mNone\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;33m\n",
       "\u001b[0m    \u001b[0mextra_body\u001b[0m\u001b[1;33m:\u001b[0m \u001b[1;34m'Body | None'\u001b[0m \u001b[1;33m=\u001b[0m \u001b[1;32mNone\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;33m\n",
       "\u001b[0m    \u001b[0mtimeout\u001b[0m\u001b[1;33m:\u001b[0m \u001b[1;34m'float | httpx.Timeout | None | NotGiven'\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mNOT_GIVEN\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;33m\n",
       "\u001b[0m\u001b[1;33m)\u001b[0m \u001b[1;33m->\u001b[0m \u001b[1;34m'ChatCompletion | Stream[ChatCompletionChunk]'\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
       "\u001b[1;31mDocstring:\u001b[0m <no docstring>\n",
       "\u001b[1;31mFile:\u001b[0m      c:\\users\\19097\\appdata\\roaming\\python\\python312\\site-packages\\openai\\resources\\chat\\completions.py\n",
       "\u001b[1;31mType:\u001b[0m      method"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "client = OpenAI(\n",
    "    base_url='https://cloud.perfxlab.cn/v1',\n",
    "    api_key=perfx_api_key\n",
    ")\n",
    "\n",
    "client.chat.completions.create?"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "61c44e0a-de54-4914-87a5-ec3e59a96347",
   "metadata": {},
   "source": [
    "## 3. LLM API\n",
    "- 流式/非流式输出\n",
    "- 单轮/多轮对话\n",
    "- token计数与上下文长度\n",
    "- temperature设置\n",
    "- 补全（completion）API"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "1382ba0d-82f3-4c84-8e80-a321004b8c45",
   "metadata": {},
   "source": [
    "### 3.1 流式/非流式输出"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 369,
   "id": "77914054-bd6f-4031-a2e6-3feec36fd596",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "北京的秋天，是一幅色彩斑斓的画卷，是大自然最细腻的笔触，也是城市最温柔的诗篇。\n",
      "\n",
      "当夏日的炎热逐渐退去，北京的秋天便悄然而至。天空变得格外高远，湛蓝如洗，仿佛能洗净一切尘埃。阳光不再那么炽热，而是变得柔和而温暖，洒在身上，带来一丝丝凉爽与舒适。微风轻拂，带着一丝丝凉意，却也带着秋天特有的清新与宁静。\n",
      "\n",
      "走在街头，你会发现，北京的秋天是色彩的盛宴。树叶由绿转黄，再由黄变红，如同调色盘上的颜料，将整座城市装扮得五彩斑斓。银杏树、枫树、梧桐树……每一种树木都以自己独特的色彩，为这座城市添上一抹亮丽的风景。走在这样的街道上，仿佛置身于一幅流动的油画之中，让人流连忘返。\n",
      "\n",
      "秋天的北京，也是收获的季节。街头巷尾，水果摊上摆满了苹果、梨、柿子等应季水果，色泽诱人，香气扑鼻。这些水果不仅丰富了人们的餐桌，也成为了秋天最甜蜜的象征。品尝一口新鲜的苹果，或是咬上一口脆甜的柿子，都是对这个季节最美好的诠释。\n",
      "\n",
      "夜晚的北京，更是别有一番风味。华灯初上，古老的城墙在灯光的映照下显得更加庄重而神秘。走在这样的夜晚，可以感受到这座城市独有的文化底蕴。无论是漫步在古老的胡同里，还是坐在一家小酒馆里品尝着秋天的特色美食，都能让人感受到北京秋天独有的宁静与美好。\n",
      "\n",
      "北京的秋天，是忙碌与宁静的交织，是繁华与自然的融合。它以自己独有的方式，讲述着这座城市的故事，吸引着每一个热爱生活的人前来探索。"
     ]
    }
   ],
   "source": [
    "# 流式输出\n",
    "client = OpenAI(\n",
    "    base_url='https://cloud.perfxlab.cn/v1',\n",
    "    api_key=perfx_api_key\n",
    ")\n",
    "\n",
    "stream = client.chat.completions.create(\n",
    "    model=\"Qwen2.5-7B-Instruct\",\n",
    "    messages=[\n",
    "        {\"role\":\"system\",\"content\":\"want you to be a chatterbox expert and answer the following in a friendly tone.\"},\n",
    "        {\"role\": \"user\", \"content\": \"写一篇北京秋天的散文\"}],\n",
    "    stream=True  # 设置为流式输出\n",
    ")\n",
    "\n",
    "for chunk in stream:\n",
    "    if chunk.choices[0].delta.content is not None:\n",
    "        print(chunk.choices[0].delta.content, end=\"\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 371,
   "id": "20dd52a4-ff33-455f-8fb0-e75e4349ea38",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "北京的秋天，是一幅色彩斑斓的画卷，是大自然最细腻的笔触，也是城市最温柔的诗篇。\n",
      "\n",
      "当夏日的炎热逐渐退去，北京的秋天便悄然而至。天空变得格外高远，湛蓝如洗，仿佛能洗净一切尘埃。阳光不再那么炽热，而是变得柔和而温暖，洒在身上，带来一丝丝凉爽与舒适。微风轻拂，带着一丝丝凉意，却也带着秋天特有的清新与宁静。\n",
      "\n",
      "走在街头，你会发现，北京的秋天是色彩的盛宴。树叶由绿转黄，再由黄变红，如同调色盘上的颜料，将整座城市装扮得五彩斑斓。银杏树、枫树、梧桐树……每一种树木都以自己独特的色彩，为这座城市添上一抹亮丽的风景。走在这样的街道上，仿佛置身于一幅流动的油画之中，让人流连忘返。\n",
      "\n",
      "秋天的北京，也是收获的季节。街头巷尾，水果摊上摆满了苹果、梨、柿子等应季水果，色泽诱人，香气扑鼻。这些水果不仅丰富了人们的餐桌，也成为了秋天最甜蜜的象征。品尝一口新鲜的苹果，或是咬上一口脆甜的柿子，都是对这个季节最美好的诠释。\n",
      "\n",
      "夜晚的北京，更是别有一番风味。华灯初上，古老的城墙在灯光的映照下显得更加庄重而神秘。走在这样的夜晚，可以感受到这座城市独有的文化底蕴。无论是漫步在古老的胡同里，还是坐在一家小酒馆里品尝着秋天的特色美食，都能让人感受到北京秋天独有的宁静与美好。\n",
      "\n",
      "北京的秋天，是忙碌与宁静的交织，是繁华与自然的融合。它以自己独有的方式，讲述着这座城市的故事，吸引着每一个热爱生活的人前来探索。\n"
     ]
    }
   ],
   "source": [
    "response = client.chat.completions.create(\n",
    "    model=\"Qwen2.5-7B-Instruct\",\n",
    "    messages=[\n",
    "        {\"role\":\"system\",\"content\":\"want you to be a chatterbox expert and answer the following in a friendly tone.\"},\n",
    "        {\"role\": \"user\", \"content\": \"写一篇北京秋天的散文\"}\n",
    "    ],\n",
    "    stream=False  # 设置为非流式输出\n",
    ")\n",
    "\n",
    "# 输出完整的内容\n",
    "print(response.choices[0].message.content)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "808015c3-ab98-4c61-ba2d-0d0a16a3defa",
   "metadata": {},
   "source": [
    "要点总结：\n",
    "- 流式输出：适用于需要实时生成和显示回复的场景\n",
    "- 非流式输出：适用于批处理、离线分析等场景"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d12a06c2-05a2-46c9-9a52-b32e9b896a04",
   "metadata": {},
   "source": [
    "### 3.2 单轮/多轮对话"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 374,
   "id": "7646dec0-46cc-493f-b540-d6d59dce7ed6",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "The autumn in Beijing is a colorful scroll, the most delicate brushstrokes of nature, and the soft poem of the city.\n"
     ]
    }
   ],
   "source": [
    "messages = [\n",
    "    {\"role\":\"system\",\"content\":\"want you to be a chatterbox expert and answer the following in a friendly tone.\"},\n",
    "    {\"role\": \"user\", \"content\": \"写一篇北京秋天的散文\"},\n",
    "    {\"role\": \"assistant\", \"content\": \"北京的秋天，是一幅色彩斑斓的画卷，是大自然最细腻的笔触，也是城市最温柔的诗篇。\"},\n",
    "    {\"role\": \"user\", \"content\": \"将其翻译成英文\"},\n",
    "]\n",
    "\n",
    "response = client.chat.completions.create(\n",
    "    model=\"Qwen2.5-7B-Instruct\",\n",
    "    messages=messages,\n",
    "    stream=False  # 设置为非流式输出\n",
    ")\n",
    "\n",
    "# 输出完整的内容\n",
    "print(response.choices[0].message.content)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "dca52de5-62e9-4762-a5e1-f648a96bfd0b",
   "metadata": {},
   "source": [
    "要点总结：\n",
    "- 大模型对话是**无状态**的，推理后端不会保存历史对话\n",
    "- 一些web聊天机器人，可以设置`history`，本质上也是先把历史对话存起来，发请求的时候再将其拼接到一起"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3ab91b90-fb2d-4bea-9779-417eddebe20d",
   "metadata": {
    "jp-MarkdownHeadingCollapsed": true
   },
   "source": [
    "### 3.3 token计数与上下文长度"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "838a38b9-3ce9-42d7-b7ce-4eb4e6f9db4f",
   "metadata": {},
   "outputs": [],
   "source": [
    "!pip install transformers\n",
    "!pip install -U huggingface_hub"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 403,
   "id": "82f13257-3431-47c7-8ae2-7fdd4c245d38",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "encoding:  [30113, 374, 537, 429, 3873]\n",
      "decoding:  today is not that bad\n",
      "\n",
      "\n",
      "encoding:  [68990, 9370, 109127, 3837, 99639, 99708, 104604, 118567, 9370, 117464, 3837, 20412, 108479, 31235, 108996, 9370]\n",
      "decoding:  今天天气很不错！\n"
     ]
    }
   ],
   "source": [
    "from transformers import AutoTokenizer\n",
    "import os\n",
    "\n",
    "# huggingface无法下载的问题，可以使用国内镜像站:https://hf-mirror.com/\n",
    "os.environ['HF_ENDPOINT'] = \"https://hf-mirror.com\"\n",
    "\n",
    "# AutoTokenizer会根据model_name去本地缓存目录检索对应的模型，检索不到则会联网下载\n",
    "# https://modelscope.cn/models/Qwen/Qwen2.5-7B-Instruct\n",
    "model_name = 'Qwen/Qwen2.5-7B-Instruct'\n",
    "tokenizer = AutoTokenizer.from_pretrained(model_name)\n",
    "\n",
    "test_sentece = 'today is not that bad'\n",
    "print('encoding: ', tokenizer.encode(test_sentece))\n",
    "print('decoding: ', tokenizer.decode([30113,   374,   537,   429,  3873]))\n",
    "print('\\n')\n",
    "\n",
    "test_sentece = '今天天气很不错！'\n",
    "print('encoding: ', tokenizer.encode(test_sentece))\n",
    "print('decoding: ', tokenizer.decode([100644, 104307, 109517, 6313]))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 397,
   "id": "4065f852-03b4-4985-9aed-0509ea449a24",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "北京的秋天，是一幅色彩斑斓的画卷，是大自然最细腻的"
     ]
    }
   ],
   "source": [
    "# max_tokens控制输出长度\n",
    "stream = client.chat.completions.create(\n",
    "    model=\"Qwen2.5-7B-Instruct\",\n",
    "    messages=[\n",
    "        {\"role\":\"system\",\"content\":\"want you to be a chatterbox expert and answer the following in a friendly tone.\"},\n",
    "        {\"role\": \"user\", \"content\": \"写一篇北京秋天的散文\"}],\n",
    "    stream=True,  # 设置为流式输出\n",
    "    max_tokens=16\n",
    ")\n",
    "\n",
    "for chunk in stream:\n",
    "    if chunk.choices[0].delta.content is not None:\n",
    "        print(chunk.choices[0].delta.content, end=\"\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 409,
   "id": "3b29c463-e493-4698-acce-c07f94aabd6f",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[68990, 9370, 109127, 3837, 99639, 99708, 104604, 118567, 9370, 117464, 3837, 20412, 108479, 31235, 108996, 9370]\n",
      "16\n"
     ]
    }
   ],
   "source": [
    "test_sentece = '北京的秋天，是一幅色彩斑斓的画卷，是大自然最细腻的'\n",
    "print(tokenizer.encode(test_sentece))\n",
    "print(len(tokenizer.encode(test_sentece)))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "82196b6f-2b4e-4881-9c14-22fb6ac7f88e",
   "metadata": {},
   "source": [
    "要点总结：\n",
    "- LLM的输入不是自然语言文本，而是分词器（tokenizer）处理后的token\n",
    "- `max_tokens`代表输出token的长度限制，一般设置成4k以下，模型输出太长可能影响效果\n",
    "- 模型上下文长度指的是模型能处理的最长样本长度，在推理阶段，上下文长度=输入+输出token长度"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b55fc838-db8b-4af8-8af4-62f42bc7b36e",
   "metadata": {
    "jp-MarkdownHeadingCollapsed": true
   },
   "source": [
    "### 3.4 temperature设置"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 439,
   "id": "bd4d2390-e806-46eb-9154-0c6dba2ac610",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "北京的秋天，那可真是美得让人心醉！从9月到11月，这个季节的北京仿佛被大自然精心装扮过，每一处都散发着迷人的魅力。秋天的北京，天空特别蓝，空气也格外清新，走在街上，你会感受到一种宁静而舒适的氛围。\n",
      "\n",
      "最让人期待的，莫过于秋天的色彩了。北京的秋天，是色彩的盛宴。从故宫的红墙到颐和园的碧水，从香山的红叶到北海的白塔，每一处都是色彩斑斓，美不胜收。尤其是香山的红叶，每年都会吸引无数游客前来观赏，那漫山遍野的红叶，如同火焰般燃烧，美得让人窒息。\n",
      "\n",
      "此外，秋天的北京还是个适合户外活动的好时节。无论是去颐和园划船，还是在北海公园散步，或是沿着长城徒步，都能让你感受到秋天的魅力。而且，秋天的北京，天气凉爽，既没有夏天的炎热，也没有冬天的寒冷，是旅游的最佳季节。\n",
      "\n",
      "当然，秋天的北京还有许多美食等着你。比如，秋天是吃烤鸭的最佳季节，外皮酥脆、肉质鲜嫩的北京烤鸭，搭配上新鲜"
     ]
    }
   ],
   "source": [
    "# low temperature\n",
    "stream = client.chat.completions.create(\n",
    "    model=\"Qwen2.5-72B-Instruct\",\n",
    "    messages=[\n",
    "        {\"role\":\"system\",\"content\":\"want you to be a chatterbox expert and answer the following in a friendly tone.\"},\n",
    "        {\"role\": \"user\", \"content\": \"描述北京的秋天\"}],\n",
    "    max_tokens=256,\n",
    "    stream=True,\n",
    "    temperature=0.2\n",
    "    \n",
    ")\n",
    "\n",
    "for chunk in stream:\n",
    "    if chunk.choices[0].delta.content is not None:\n",
    "        print(chunk.choices[0].delta.content, end=\"\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 441,
   "id": "8fe21360-07dc-4065-a878-5666ba2c9160",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "北京的秋天，那可真是美得让人 licking their lips 啊！说到秋天，很多人心目中最美的秋天不在其他地方，而是在北京。这里的秋天从9月初开始，一直持续到11月中旬左右，晴朗的日子居多，温度介于15℃到25℃之间，非常适宜出游，一点都不会感觉太热或者太冷。\n",
      "\n",
      "到了北京市区，你会发现满城的银杏树叶由绿转黄，仿佛一夜之间所有的一切都换上了金黄色的外衣。故宫、北海公园、颐和园等皇家园林中的古建筑与黄叶相互映衬，更添了几分历史与季节交融的美。尤其是走在颐和园的长廊里，隔空看着金黄的树叶和它在昆明湖中的倒影，简直美得让人词穷！\n",
      "\n",
      "秋天还是北京最好的季节之一，各种文化活动也在这个时令相继展开。比如在北京国际音乐节上，可以欣赏到来自世界各地的精彩表演；此外，还会举办大大小小的菊展，各个公园、街头会出现五彩缤纷的菊花，为城市增添了不少动态的美。总之，北京的秋天是一年中最明媚最愉快的时候！\n",
      "\n",
      "听到这些描述，是不是已经开始向往北京"
     ]
    }
   ],
   "source": [
    "# high temperature\n",
    "stream = client.chat.completions.create(\n",
    "    model=\"Qwen2.5-72B-Instruct\",\n",
    "    messages=[\n",
    "        {\"role\":\"system\",\"content\":\"want you to be a chatterbox expert and answer the following in a friendly tone.\"},\n",
    "        {\"role\": \"user\", \"content\": \"描述北京的秋天\"}],\n",
    "    max_tokens=256,\n",
    "    stream=True,\n",
    "    temperature=1.3\n",
    ")\n",
    "\n",
    "for chunk in stream:\n",
    "    if chunk.choices[0].delta.content is not None:\n",
    "        print(chunk.choices[0].delta.content, end=\"\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "5708686a-483d-4775-b593-06cf93a3f64c",
   "metadata": {},
   "source": [
    "要点总结：\n",
    "- temperature取值通常在[0, 2]之间，默认值为1，设置的太大可能输出乱码\n",
    "- low temperature：输出趋于稳定、保守，选择最常见和确定的表达，适合生成可靠的、标准化的内容。\n",
    "- middle temperature：输出既多样又合理，能保持逻辑性和丰富性，适合大多数创意性任务。\n",
    "- high temperature：输出更加随机化，富有想象力，可能会引入一些较为大胆或不确定的表达，适合需要高创造力的场景。"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a8aecc4e-7b02-4e72-af6f-72a7dc5a7970",
   "metadata": {},
   "source": [
    "### 3.5 补全API"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 443,
   "id": "0b4e7785-86a9-4a11-86d3-9b5e7d3fb54c",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Completion(id='cmpl-9526ff59a8f64d45996354ae5700e25f', choices=[CompletionChoice(finish_reason='length', index=0, logprobs=None, text='如何制作一道美味的家常菜。\\n当然可以！这里我为您介绍')], created=1728548207, model='Qwen2.5-7B-Instruct-fp16', object='text_completion', system_fingerprint=None, usage=CompletionUsage(completion_tokens=16, prompt_tokens=2, total_tokens=18, completion_tokens_details=None, prompt_tokens_details=None))\n"
     ]
    }
   ],
   "source": [
    "# https://platform.openai.com/docs/guides/completions\n",
    "response = client.completions.create(\n",
    "  model=\"Qwen2.5-7B-Instruct\",\n",
    "  prompt=\"请你介绍\"\n",
    ")\n",
    "\n",
    "print(response)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 104,
   "id": "b6450a2f-bdc7-4e6d-9a6f-f305b3caf11a",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "\u001b[1;31mSignature:\u001b[0m\n",
       "\u001b[0mclient\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mcompletions\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mcreate\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m\n",
       "\u001b[0m    \u001b[1;33m*\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;33m\n",
       "\u001b[0m    \u001b[0mmodel\u001b[0m\u001b[1;33m:\u001b[0m \u001b[1;34m\"Union[str, Literal['gpt-3.5-turbo-instruct', 'davinci-002', 'babbage-002']]\"\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;33m\n",
       "\u001b[0m    \u001b[0mprompt\u001b[0m\u001b[1;33m:\u001b[0m \u001b[1;34m'Union[str, List[str], Iterable[int], Iterable[Iterable[int]], None]'\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;33m\n",
       "\u001b[0m    \u001b[0mbest_of\u001b[0m\u001b[1;33m:\u001b[0m \u001b[1;34m'Optional[int] | NotGiven'\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mNOT_GIVEN\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;33m\n",
       "\u001b[0m    \u001b[0mecho\u001b[0m\u001b[1;33m:\u001b[0m \u001b[1;34m'Optional[bool] | NotGiven'\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mNOT_GIVEN\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;33m\n",
       "\u001b[0m    \u001b[0mfrequency_penalty\u001b[0m\u001b[1;33m:\u001b[0m \u001b[1;34m'Optional[float] | NotGiven'\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mNOT_GIVEN\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;33m\n",
       "\u001b[0m    \u001b[0mlogit_bias\u001b[0m\u001b[1;33m:\u001b[0m \u001b[1;34m'Optional[Dict[str, int]] | NotGiven'\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mNOT_GIVEN\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;33m\n",
       "\u001b[0m    \u001b[0mlogprobs\u001b[0m\u001b[1;33m:\u001b[0m \u001b[1;34m'Optional[int] | NotGiven'\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mNOT_GIVEN\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;33m\n",
       "\u001b[0m    \u001b[0mmax_tokens\u001b[0m\u001b[1;33m:\u001b[0m \u001b[1;34m'Optional[int] | NotGiven'\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mNOT_GIVEN\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;33m\n",
       "\u001b[0m    \u001b[0mn\u001b[0m\u001b[1;33m:\u001b[0m \u001b[1;34m'Optional[int] | NotGiven'\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mNOT_GIVEN\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;33m\n",
       "\u001b[0m    \u001b[0mpresence_penalty\u001b[0m\u001b[1;33m:\u001b[0m \u001b[1;34m'Optional[float] | NotGiven'\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mNOT_GIVEN\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;33m\n",
       "\u001b[0m    \u001b[0mseed\u001b[0m\u001b[1;33m:\u001b[0m \u001b[1;34m'Optional[int] | NotGiven'\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mNOT_GIVEN\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;33m\n",
       "\u001b[0m    \u001b[0mstop\u001b[0m\u001b[1;33m:\u001b[0m \u001b[1;34m'Union[Optional[str], List[str], None] | NotGiven'\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mNOT_GIVEN\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;33m\n",
       "\u001b[0m    \u001b[0mstream\u001b[0m\u001b[1;33m:\u001b[0m \u001b[1;34m'Optional[Literal[False]] | Literal[True] | NotGiven'\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mNOT_GIVEN\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;33m\n",
       "\u001b[0m    \u001b[0mstream_options\u001b[0m\u001b[1;33m:\u001b[0m \u001b[1;34m'Optional[ChatCompletionStreamOptionsParam] | NotGiven'\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mNOT_GIVEN\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;33m\n",
       "\u001b[0m    \u001b[0msuffix\u001b[0m\u001b[1;33m:\u001b[0m \u001b[1;34m'Optional[str] | NotGiven'\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mNOT_GIVEN\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;33m\n",
       "\u001b[0m    \u001b[0mtemperature\u001b[0m\u001b[1;33m:\u001b[0m \u001b[1;34m'Optional[float] | NotGiven'\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mNOT_GIVEN\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;33m\n",
       "\u001b[0m    \u001b[0mtop_p\u001b[0m\u001b[1;33m:\u001b[0m \u001b[1;34m'Optional[float] | NotGiven'\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mNOT_GIVEN\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;33m\n",
       "\u001b[0m    \u001b[0muser\u001b[0m\u001b[1;33m:\u001b[0m \u001b[1;34m'str | NotGiven'\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mNOT_GIVEN\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;33m\n",
       "\u001b[0m    \u001b[0mextra_headers\u001b[0m\u001b[1;33m:\u001b[0m \u001b[1;34m'Headers | None'\u001b[0m \u001b[1;33m=\u001b[0m \u001b[1;32mNone\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;33m\n",
       "\u001b[0m    \u001b[0mextra_query\u001b[0m\u001b[1;33m:\u001b[0m \u001b[1;34m'Query | None'\u001b[0m \u001b[1;33m=\u001b[0m \u001b[1;32mNone\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;33m\n",
       "\u001b[0m    \u001b[0mextra_body\u001b[0m\u001b[1;33m:\u001b[0m \u001b[1;34m'Body | None'\u001b[0m \u001b[1;33m=\u001b[0m \u001b[1;32mNone\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;33m\n",
       "\u001b[0m    \u001b[0mtimeout\u001b[0m\u001b[1;33m:\u001b[0m \u001b[1;34m'float | httpx.Timeout | None | NotGiven'\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mNOT_GIVEN\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;33m\n",
       "\u001b[0m\u001b[1;33m)\u001b[0m \u001b[1;33m->\u001b[0m \u001b[1;34m'Completion | Stream[Completion]'\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
       "\u001b[1;31mDocstring:\u001b[0m <no docstring>\n",
       "\u001b[1;31mFile:\u001b[0m      c:\\users\\19097\\appdata\\roaming\\python\\python312\\site-packages\\openai\\resources\\completions.py\n",
       "\u001b[1;31mType:\u001b[0m      method"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "client.completions.create?"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "2b0cb69e-9544-458c-af60-b19050f4b9e8",
   "metadata": {},
   "source": [
    "## 4. 多模态模型API\n",
    "- MiniCPM文档：https://github.com/OpenBMB/MiniCPM-V/blob/main/README_zh.md"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 274,
   "id": "631e2d4c-ed7b-4623-9a07-070d74c86ad0",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<img src=\"\" width=\"800\" height=\"500\"/>"
      ],
      "text/plain": [
       "<IPython.core.display.Image object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "import base64\n",
    "from IPython.display import Image, display\n",
    "\n",
    "def image_to_base64(image_path):\n",
    "    with open(image_path, \"rb\") as image_file:\n",
    "        encoded_string = base64.b64encode(image_file.read())\n",
    "    return encoded_string.decode('utf-8')\n",
    "\n",
    "image_path = \"./image.png\"\n",
    "image_base64 = image_to_base64(image_path)\n",
    "\n",
    "# 创建一个包含 base64 编码的图片的 URL\n",
    "image_url = f\"data:image/png;base64,{image_base64}\"\n",
    "\n",
    "# 使用 IPython.display.Image 显示图片\n",
    "display(Image(url=image_url, width=800, height=500))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 270,
   "id": "c8c230af-8852-4a3e-b3c1-e6258de49032",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "要回答2008年奥运会获得金牌数最多的3个国家一共获得了多少枚金牌，我们需要依次找出金牌数最多的三个国家，并将它们的金牌数相加。\n",
      "\n",
      "从图像中的奖牌榜可以看出，金牌数最多的三个国家及其金牌数分别是：\n",
      "\n",
      "1. 中国 (CHN) - 48枚金牌\n",
      "2. 美国 (USA) - 36枚金牌\n",
      "3. 俄罗斯 (RUS) - 24枚金牌\n",
      "\n",
      "接下来，我们将这三个国家的金牌数相加：\n",
      "\n",
      "48 + 36 + 24 = 108\n",
      "\n",
      "因此，2008年奥运会获得金牌数最多的3个国家一共获得了108枚金牌。"
     ]
    }
   ],
   "source": [
    "stream = client.chat.completions.create(\n",
    "    model=\"MiniCPM-V-2_6\",\n",
    "    messages=[\n",
    "        {\"role\": \"user\", \"content\": [\n",
    "            {\n",
    "                \"type\": \"text\",\n",
    "                \"text\": \"2008年奥运会获得金牌数最多的3个国家一共获得了多少枚金牌？请逐步分析\"\n",
    "            },\n",
    "            {\n",
    "                \"type\": \"image_url\",\n",
    "                \"image_url\": {\n",
    "                    \"url\": f\"data:image/jpeg;base64,{image_base64}\"\n",
    "                },\n",
    "            },\n",
    "        ]}],\n",
    "    temperature=1,\n",
    "    stream=True\n",
    ")\n",
    "\n",
    "for chunk in stream:\n",
    "    if chunk.choices[0].delta.content is not None:\n",
    "        print(chunk.choices[0].delta.content, end=\"\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "486c4af2-bc28-4731-85ce-ed6523f4ecc3",
   "metadata": {},
   "source": [
    "## 5. Embedding模型 API"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 453,
   "id": "da86fbe3-58db-4211-bf05-0e1cf4e66eec",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "length of the output embedding:  1024\n",
      "[-0.03619103878736496, -0.03774731606245041, -0.004645940847694874, 0.022535482421517372, 0.01621883362531662, -0.08507640659809113, 0.03091190755367279, -0.02497669868171215, -0.007903438992798328, -0.02712802216410637]\n"
     ]
    }
   ],
   "source": [
    "text = \"What are embeddings?\"\n",
    "text = text.replace(\"\\n\", \" \")\n",
    "\n",
    "emb = client.embeddings.create(input=[text], model=\"BAAI/bge-m3\").data[0].embedding\n",
    "\n",
    "print('length of the output embedding: ', len(emb))\n",
    "print(emb[:10])"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "57df025c-92c3-4c80-8cfd-7df263830d63",
   "metadata": {},
   "source": [
    "要点总结：\n",
    "- 语义向量模型(Embedding Model)被广泛应用于搜索(Search)、问答(QA)、大语言模型检索增强(RAG)等应用场景之中\n",
    "- 不同模型对输入文本长度有限制，例如本次使用的bge-m3，输入长度最大为8192"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "5bab4cf9-fb28-4ac9-9386-5156a256b610",
   "metadata": {},
   "source": [
    "## 6. 文生图API"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 461,
   "id": "36a214f1-cdcc-473d-a65a-8d440d35224e",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'images': ['http://111.23.54.37:30120/text2img/1728548769167214914.jpg?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=6dJB2zvkwcdsMc0cbzJK%2F20241010%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20241010T082609Z&X-Amz-Expires=3600&X-Amz-SignedHeaders=host&X-Amz-Signature=32cf0ae67df3c9997f372a08b6403486d37c8203ec1ec331902dda476c94f910'], 'info': '{\"prompt\": \"a dog running in the rain\", \"all_prompts\": [\"a dog running in the rain\"], \"negative_prompt\": \"people, text\", \"all_negative_prompts\": [\"people, text\"], \"seed\": 75, \"all_seeds\": [75], \"subseed\": 1917501686, \"all_subseeds\": [1917501686], \"subseed_strength\": 0, \"width\": 512, \"height\": 512, \"sampler_name\": \"DPM++ 2M\", \"cfg_scale\": 7.0, \"steps\": 30, \"batch_size\": 1, \"restore_faces\": false, \"face_restoration_model\": null, \"sd_model_name\": \"v1-5-pruned-emaonly\", \"sd_model_hash\": \"6ce0161689\", \"sd_vae_name\": null, \"sd_vae_hash\": null, \"seed_resize_from_w\": -1, \"seed_resize_from_h\": -1, \"denoising_strength\": null, \"extra_generation_params\": {}, \"index_of_first_image\": 0, \"infotexts\": [\"a dog running in the rain\\\\nNegative prompt: people, text\\\\nSteps: 30, Sampler: DPM++ 2M, CFG scale: 7.0, Seed: 75, Size: 512x512, Model hash: 6ce0161689, Model: v1-5-pruned-emaonly, Version: v1.7.0\"], \"styles\": [], \"job_timestamp\": \"20241010162603\", \"clip_skip\": 1, \"is_using_inpainting_conditioning\": false, \"version\": \"v1.7.0\"}', 'parameters': {'alwayson_scripts': {}, 'batch_size': 1, 'cfg_scale': 7, 'comments': None, 'denoising_strength': None, 'disable_extra_networks': False, 'do_not_save_grid': False, 'do_not_save_samples': False, 'enable_hr': False, 'eta': None, 'firstphase_height': 0, 'firstphase_width': 0, 'height': 512, 'hr_checkpoint_name': None, 'hr_negative_prompt': '', 'hr_prompt': '', 'hr_resize_x': 0, 'hr_resize_y': 0, 'hr_sampler_name': None, 'hr_scale': 2, 'hr_second_pass_steps': 0, 'hr_upscaler': None, 'n_iter': 1, 'negative_prompt': 'people, text', 'override_settings': {'sd_model_checkpoint': 'v1-5-pruned-emaonly.safetensors [6ce0161689]'}, 'override_settings_restore_afterwards': True, 'prompt': 'a dog running in the rain', 'refiner_checkpoint': None, 'refiner_switch_at': None, 'restore_faces': None, 's_churn': None, 's_min_uncond': None, 's_noise': None, 's_tmax': None, 's_tmin': None, 'sampler_index': 'Euler', 'sampler_name': 'DPM++ 2M', 'save_images': False, 'script_args': [], 'script_name': None, 'seed': 75, 'seed_resize_from_h': -1, 'seed_resize_from_w': -1, 'send_images': True, 'steps': 30, 'styles': None, 'subseed': -1, 'subseed_strength': 0, 'tiling': None, 'width': 512}}\n"
     ]
    }
   ],
   "source": [
    "import os\n",
    "import requests\n",
    "\n",
    "headers = {\n",
    "    'Content-Type': 'application/json',\n",
    "    'Authorization':  f'Bearer {'sk-xnitUDyQf5z0AFaV518f5606966d49Fb8bA1E940B4FcA087'}'\n",
    "}\n",
    "\n",
    "def generate_image():\n",
    "    url = \"https://cloud.perfxlab.cn/sdapi/v1/txt2img\"  \n",
    "    \n",
    "    # 请求参数\n",
    "    payload = {\n",
    "        \"model\": \"StableDiffusion\",\n",
    "        \"prompt\": \"a dog running in the rain\",\n",
    "        \"negative_prompt\": \"people, text\",\n",
    "        \"steps\": 30,\n",
    "        \"seed\": 75,\n",
    "        \"width\": 512,\n",
    "        \"height\": 512,\n",
    "        \"batch_size\": 1,\n",
    "        \"n_iter\": 1\n",
    "    }\n",
    "    \n",
    "    response = requests.post(url, headers=headers, json=payload)\n",
    "    \n",
    "    if response.status_code == 200:\n",
    "        data = response.json()\n",
    "        print(data)\n",
    "    else:\n",
    "        print(f\"Failed to generate image. Status code: {response.status_code}\")\n",
    "\n",
    "generate_image()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "2b1ec899-a29c-49aa-94b3-9f38e8eecbe9",
   "metadata": {},
   "source": [
    "要点总结：\n",
    "- Stable Diffusion 模型最初是为处理英文文本而设计的，因此在中文支持方面可能效果不佳，建议使用英文prompt"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c67878a9-aebd-4689-8b93-7fa91147eede",
   "metadata": {},
   "source": [
    "## 7. 文生语音API"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 433,
   "id": "54ce5df4-31da-4a7d-8a3e-6cb95bb04cdb",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'audio_files': [{'filename': '161303_use2.66s-audio0s-seed1031.pt-te0.1-tp0.701-tk20-textlen10-48137-merge_new.wav', 'inference_time': 2.66, 'url': 'http://111.23.54.37:30120/text2voice/161303_use2.66s-audio0s-seed1031.pt-te0.1-tp0.701-tk20-textlen10-48137-merge_new.wav?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=6dJB2zvkwcdsMc0cbzJK%2F20241010%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20241010T081304Z&X-Amz-Expires=3600&X-Amz-SignedHeaders=host&X-Amz-Signature=f9a89c0cc8624f3899d69c9d4696f1a44aedcc5ef92f32fdb361d8c91cb41a8d'}], 'code': 0, 'filename': '161303_use2.66s-audio0s-seed1031.pt-te0.1-tp0.701-tk20-textlen10-48137-merge_new.wav', 'msg': 'ok', 'url': 'http://111.23.54.37:30120/text2voice/161303_use2.66s-audio0s-seed1031.pt-te0.1-tp0.701-tk20-textlen10-48137-merge_new.wav?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=6dJB2zvkwcdsMc0cbzJK%2F20241010%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20241010T081304Z&X-Amz-Expires=3600&X-Amz-SignedHeaders=host&X-Amz-Signature=f9a89c0cc8624f3899d69c9d4696f1a44aedcc5ef92f32fdb361d8c91cb41a8d'}\n"
     ]
    }
   ],
   "source": [
    "import requests\n",
    "import json\n",
    "import os\n",
    "\n",
    "url = \"https://cloud.perfxlab.cn/chattts/tts\"\n",
    "headers = {\n",
    "    'Content-Type': 'application/json',\n",
    "    'Authorization': f'Bearer {'sk-xnitUDyQf5z0AFaV518f5606966d49Fb8bA1E940B4FcA087'}',\n",
    "}\n",
    "payload = json.dumps({\n",
    "    \"model\": \"ChatTTS\",\n",
    "    \"text\": \"早上好呀，吃饭了么？\",\n",
    "    \"prompt\": \"[break_5]\",\n",
    "    \"speed\": 5,\n",
    "    \"temperature\": 0.1,\n",
    "    \"text_seed\": 42,\n",
    "    \"top_k\": 20,\n",
    "    \"top_p\": 0.701,\n",
    "    \"voice\": \"1031.pt\",\n",
    "    \"refine_max_new_token\": 384,\n",
    "    \"infer_max_new_token\": 2048\n",
    "})\n",
    "\n",
    "response = requests.post(url, headers=headers, data=payload)\n",
    "response_data = response.json()\n",
    "print(response_data)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "82dbf3ed-53db-415d-9c03-00734237369d",
   "metadata": {},
   "source": [
    "## 8. 其他工具类API"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 435,
   "id": "28dd0a9c-dae5-4cc6-884e-b2c3b35b6471",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Model(id='Qwen2.5-7B-Instruct', created=1626777600, object='model', owned_by='custom', permission=None, root='Qwen2.5-7B-Instruct', parent=None)\n",
      "Model(id='StableDiffusion', created=1626777600, object='model', owned_by='custom', permission=None, root='StableDiffusion', parent=None)\n",
      "Model(id='MiniCPM-V-2_6', created=1626777600, object='model', owned_by='custom', permission=None, root='MiniCPM-V-2_6', parent=None)\n",
      "Model(id='BAAI/bge-m3', created=1626777600, object='model', owned_by='custom', permission=None, root='BAAI/bge-m3', parent=None)\n",
      "Model(id='ChatTTS', created=1626777600, object='model', owned_by='custom', permission=None, root='ChatTTS', parent=None)\n",
      "Model(id='Qwen2.5-72B-Instruct', created=1626777600, object='model', owned_by='custom', permission=None, root='Qwen2.5-72B-Instruct', parent=None)\n"
     ]
    }
   ],
   "source": [
    "from openai import OpenAI\n",
    "\n",
    "client = OpenAI(\n",
    "    base_url='https://cloud.perfxlab.cn/v1',\n",
    "    api_key='sk-xnitUDyQf5z0AFaV518f5606966d49Fb8bA1E940B4FcA087'\n",
    ")\n",
    "\n",
    "for m in client.models.list().data:\n",
    "    print(m)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.12.4"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
